package com.movie.controller;

import com.movie.dto.JwtResponse;
import com.movie.dto.LoginRequest;
import com.movie.dto.LoginResponse;
import com.movie.dto.RegisterRequest;
import com.movie.entity.Admin;
import com.movie.entity.User;
import com.movie.mapper.AdminMapper;
import com.movie.mapper.UserMapper;
import com.movie.service.impl.UserDetailsServiceImpl;
import com.movie.util.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;

@RestController
@RequestMapping("/api/auth")
@CrossOrigin(origins = "http://localhost:5173", allowCredentials = "true")
public class AuthController {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private UserDetailsServiceImpl userDetailsService;

    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private AdminMapper adminMapper;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @PostMapping("/login")
    public ResponseEntity<?> createAuthenticationToken(@RequestBody LoginRequest loginRequest) throws Exception {
        String username = loginRequest.getUsername();
        String password = loginRequest.getPassword();
        String loginType = loginRequest.getLoginType();

        UserDetails userDetails;
        Long userId;
        String role;

        try {
            if ("admin".equalsIgnoreCase(loginType)) {
                Admin admin = adminMapper.findByUsername(username);
                if (admin == null) {
                    throw new BadCredentialsException("Incorrect admin username or password");
                }

                String dbPasswordHash = admin.getPassword();

                if (!passwordEncoder.matches(password, dbPasswordHash)) {
                    throw new BadCredentialsException("Incorrect admin username or password");
                }
                userDetails = userDetailsService.loadAdminByUsername(username);
                userId = admin.getId();
                role = "ROLE_ADMIN";
            } else {
                Authentication authentication = authenticationManager.authenticate(
                        new UsernamePasswordAuthenticationToken(username, password)
                );
                userDetails = (UserDetails) authentication.getPrincipal();
                User user = userMapper.findByUsername(username);
                userId = (user != null) ? user.getId() : null;
                if (userDetails.getAuthorities() != null && !userDetails.getAuthorities().isEmpty()) {
                    role = userDetails.getAuthorities().iterator().next().getAuthority();
                } else {
                    role = (user != null && user.getRole() == 1) ? "ROLE_ADMIN" : "ROLE_USER";
                }
            }

        } catch (BadCredentialsException e) {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("用户名或密码错误");
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("登录失败: " + e.getMessage());
        }

        final String jwt = jwtUtil.generateToken(userDetails);

        return ResponseEntity.ok(new LoginResponse(jwt, userId, userDetails.getUsername(), role));
    }

    @PostMapping("/register")
    public ResponseEntity<?> registerUser(@RequestBody RegisterRequest registerRequest) {
        if (userMapper.existsByUsername(registerRequest.getUsername()) > 0) {
            return ResponseEntity
                    .badRequest()
                    .body("Error: Username is already taken!");
        }

        User user = new User();
        user.setUsername(registerRequest.getUsername());
        user.setEmail(registerRequest.getEmail());
        user.setPassword(passwordEncoder.encode(registerRequest.getPassword()));
        user.setRole(0);
        user.setBalance(BigDecimal.ZERO);

        try {
            userMapper.insert(user);
            return ResponseEntity.ok("User registered successfully!");
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error occurred during registration.");
        }
    }
} 